Lists and Functions

This is not really a separate topic: it is a great integration of two important topics. In particular, we'll point out one gotcha.

We're used to functions having no effect on the variables that we pass in:


In [ ]:
# lets remember something we already explored

a = [0,1]
b = a
a[0] = 42
# what does b contain??

You can run into the same issue when working with functions

Consider the function below, val is defined in the function, so it does NOT exist outside of the function.


In [6]:
x = 3

def add_3(val):
    val = val + 3
    return val

print 'add_3(x) ==', add_3(x)
# Above, the function only modified it's own variable, so x stays the same
print 'x still is: ', x


add_3(x) == 6
x still is:  3

In [5]:
## What happens if you try to print val?

But once we start using mutable data types like lists, things become tricky:


In [ ]:
x = [1, 2, 3, 5]

def add_3(val):
    val[2] = val[2] + 3
    return val

print add_3(x)
# Now, our function is modifying the contents of the list, and both variables still point to the same list
# So the list x refers to *is* modified
print x

So, the issue here is our function is no longer changing val so that it points at a new "thing." Instead, we're taking the list that val points to (the same list x points to) and modifying it.

Tricky, but important!

Lets explore functions a little closer


In [ ]:
## functions do not need to take input

def print_hello():
    print "hello"

In [ ]:
## does print_hello  return anything?
## ret = print_hello()

In [ ]:
## we can update our function to take input
## and add a doc string so we can see what it does

def say_hello(input):
    """ Prints a kind greeting to our input
    returns nothing"""
    print 'Hello ', input
    
say_hello('Penelope')

In [ ]:
## pass out new function a variety of objects, how does it handle it
## eg say_hello({'crazy_dictionary': [1,2,3,4]})

In [7]:
## We can also give our function default values, and explicity tell it to return nothing

def say_long_hello(firstname, lastname = 'Smith'):
    """ Say a kind hello to firstname, lastname
    (default lastname is 'Smith')"""
    print 'Hello', firstname, lastname
    return None

In [ ]:
## try it out by passing just a firstname

## try again by passing a firstname and a lastname

In [9]:
## We can also have it return something
def say_odd_hello(firstname, junk, lastname="Smith"):
    """Print a kind hello to firstname, lastname, identify junk, 
    and return junk"""
    print 'Hello', firstname, lastname
    print 'This is your junk:', junk
    return junk

In [ ]:
## what happens when you change the order of your inputs so the default variable
## lastname = "Smith", comes before undefined junk?